package leetcode.code6077;

import java.util.List;
import java.util.Stack;

import leetcode.IDebug;
import leetcode.helper.H;

public class Solution implements IDebug {

//	class ArrayStack {
//		int[] stack;
//		int p;
//
//		public Stack(int size) {
//			stack = new int[size];
//			p = 0;
//		}
//
//		public void add(int o) {
//
//		}
//
//	}
	int mod = (int) 1e9 + 7;

	public int totalStrength(int[] strength) {
		// strength[] = [1, 3, 2, 4, 5, 2, 4, 2, 1]
		int len = strength.length;
		int[] l = new int[len];
		int[] r = new int[len];
		Stack<Integer> stack = new Stack<>();
		for (int i = 0; i < len; i++) {
			int cur = strength[i];
			while (!stack.isEmpty() && strength[stack.peek()] >= cur) {
				stack.pop();
			}
			l[i] = stack.isEmpty() ? -1 : stack.peek();
			stack.add(i);
		}
		// l[] = [-1, 0, 0, 2, 3, 0, 5, 0, -1]
		stack = new Stack<>();
		for (int i = len - 1; i >= 0; i--) {
			int cur = strength[i];
			while (!stack.isEmpty() && strength[stack.peek()] > cur) {
				stack.pop();
			}
//			r[i] = stack.isEmpty() ? -1 : stack.peek();// 
			r[i] = stack.isEmpty() ? len : stack.peek();// 
			stack.add(i);
		}
		// r[] = [8, 2, 5, 5, 5, 7, 7, 8, -1]
		// [1, 3, 2, 4, 5, 2, 4, 2, 1]
		// [1,3,2,4,5,2]
		// [i-2,i-1,i,i+1,i+2,i+3]
		// [i,i] ,[i-1,i],[i,i+1],[i-1,i+1],[i,i+2],[i-1,i+2]
		// 1.sum[i,i] = sums[i+1] - sums[i]
		// 2.sum[i-1,i] = sums[i+1] - sums[i - 1]
		// 3.sum[i,i+1] = sums[i+2] - sums[i]
		// 4.sum[i-1,i+1] = sums[i+2] - sums[i - 1]
		// 5.sum[i,i+2] = sums[i+3] - sums[i]
		// 6.sum[i-1,i+2] = sums[i+3] - sums[i - 1]
		// sum[1.2.3.4.5.6] = 3*sums[i+1,i+3] - 2*sums[i-1,i] 错这里了
		// sum[1.2.3.4.5.6] = 3*sums[i+1,r[i]] - 2*sums[l[i]+1,i] 错这里了
		// sum[1.2.3.4.5.6] = 2*sums[i+1,i+3] - 3*sums[i-1,i]
		// sum[1.2.3.4.5.6] = 2*sums[i+1,r[i]] - 3*sums[l[i]+1,i]
		// =(r[i]-i)*sums[i+1,r[i]]-(i-l[i])*sums[l[i]+1,i]
		// =(r[i]-i)*(sumsums[r[i]+1]-sumsums[i+1])-(i-l[i])*(sumsums[i+1]-sumsums[l[i]+1]);
		// =(i-l[i])*sums[i+1,r[i]]-(r[i]-i)*sums[l[i]+1,i]
		int[] sums = new int[len + 1];
		int[] sumsums = new int[len + 2];
		for (int i = 1; i < len + 1; i++) {
			sums[i] = sums[i - 1] + strength[i - 1];
		}
		for (int i = 1; i < len + 2; i++) {
			sumsums[i] = sumsums[i - 1] + sums[i - 1];
		}
		long ans = 0;
		for (int i = 0; i < len; i++) {
			long cur = (i - l[i]) * (sumsums[r[i] + 1] - sumsums[i + 1]) - (r[i] - i) * (sumsums[i + 1] - sumsums[l[i] + 1]);
			ans += (cur * strength[i]) % mod;
			ans %= mod;
		}
		return (int) ans;
	}

	@Override
	public void debug4() {
		H.compare(44, this.totalStrength(H.str2array3("[1,3,1,2]")));
		this.totalStrength(H.str2array3("[1,3,2,4,5,2,4,2,1]"));

	}

	@Override
	public void debug3() {
		// TODO Auto-generated method stub

	}

	@Override
	public void debug2() {
		// TODO Auto-generated method stub

	}

	@Override
	public void debug1() {
		// TODO Auto-generated method stub

	}

	public static void main(String[] args) {
		Solution so = new Solution();
		so.debug1();
		so.debug2();
		so.debug3();
		so.debug4();
	}

}
